<?php
/*
  Licensed to the Apache Software Foundation (ASF) under one or more
  contributor license agreements.  See the NOTICE file distributed with
  this work for additional information regarding copyright ownership.
  The ASF licenses this file to You under the Apache License, Version 2.0
  (the "License"); you may not use this file except in compliance with
  the License.  You may obtain a copy of the License at

      http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.
*/

/**
 * \file
 */
/// signifies an error with the submitted option
define("NAMEERR", 1);
/// signifies an error with the submitted request
define("REQUESTERR", 1 << 1);

$AWSKEY;
$AWSSECRET;
function populateCredentials()
{
$getawskey = mysql_query("SELECT pub_key FROM provkeys WHERE provider='ec2' LIMIT 1");
if($getawskey)
{
		global $AWSKEY;
		$AWSKEY = mysql_result($getawskey,0);
}
$getawssecret = mysql_query("SELECT pri_key FROM provkeys WHERE provider='ec2' LIMIT 1");
if($getawssecret)
{
		global $AWSSECRET;
		$AWSSECRET = mysql_result($getawssecret,0);
}
}

////////////////////////////////////////////////////////////////////////////////
///
/// \fn getXMLData()
///
/// \brief Gets the XML Data associated with the cloud provider and stores it in an XML file
///
////////////////////////////////////////////////////////////////////////////////
function getXMLData($parameters, $host)
{
	populateCredentials();
	global $AWSKEY, $AWSSECRET;
	// Build out the variables
	$domain = "http://$host/";
	$parameters['ExecutableBy.1'] = 'all';   
	$parameters['Owner.1'] = 'amazon';   

	$parameters['Filter.1.Name'] = 'root-device-type';  
	$parameters['Filter.1.Value'] = 'ebs';   
	$parameters['Filter.2.Name'] = 'image-type';  
	$parameters['Filter.2.Value'] = 'machine';
	$parameters['Filter.3.Name'] = 'state';  
	$parameters['Filter.3.Value'] = 'available';
	$parameters['Filter.4.Name'] = 'owner-alias';
	$parameters['Filter.4.Value'] = 'amazon';

	$parameters['AWSAccessKeyId'] = $AWSKEY; //'AKIAJOWEQSVMR4EJ7N7Q';
	$parameters['Timestamp'] = date('c');
	$parameters['Version'] = '2012-03-01';
	$parameters['SignatureMethod'] = 'HmacSHA256';
	$parameters['SignatureVersion'] = '2';

	// Write the signature
	$signature = "GET\n";
	$signature .= "$host\n";
	$signature .= "/\n";

	$sigparams = $parameters;
	ksort($sigparams);

	$first = true;
	foreach($sigparams as $key=>$param) 
	{
		//echo "Key: $key; Value: $param<br />\n";
		$signature .= (!$first ? '&' : '') . rawurlencode($key) . '=' . rawurlencode($param);
		$first = false;
	}

	//$signature = hash_hmac('sha256', $signature, 'sY3S+6M0zh4TSMaoLSY6dmqULHD8jsk3GiuXyq1s', true);
	$signature = hash_hmac('sha256', $signature, $AWSSECRET, true);
	$signature = base64_encode($signature);
  
	$parameters['Signature'] = $signature;
	$url = $domain . '?';
	$first = true;
	foreach($parameters as $key=>$param) {
		$url .= (!$first ? '&' : '') . rawurlencode($key) . '=' . rawurlencode($param);
		$first = false;
	}

	//echo $url;

	$dom = new DOMDocument();
	$dom->load($url);
	$dom->save('/usr/tmp/AMIresponse.xml');
	//return $output;
}

////////////////////////////////////////////////////////////////////////////////
///
/// \fn parseXMLFile()
///
/// \brief Parses the received XML file and retrieves the Images offered by the providers
///
////////////////////////////////////////////////////////////////////////////////
function parseXMLFile()
{	
	global $continue, $count, $query;
	$xml = simplexml_load_file("/usr/tmp/AMIresponse.xml");

	$request_id = $xml->children();

	$query1 = "SELECT * FROM ec2ImageList";
	$execq = doQuery($query1, 101);
	
	while($row = mysql_fetch_assoc($execq))
	{
			$query1 = "DELETE FROM ec2ImageList";
			$continue = 1;
			break;
	}
	
	if($continue == 1)
	{
		doQuery($query1, 315);
	}
	
	static $count = 1;
	foreach($xml->imagesSet[0]->item as $item)
	{
		$a=0;
		foreach($item->children() as $child)
		{
			if($child->getName() == "name")
	  		{
	        		++$a;
	  		}

	 		if($child->getName() == "description")
		   	{
	   			++$a;
		   	}
  			if($a==2)
			{
				$desc = str_replace('"', "", $item->description);
				$desc1 = str_replace("'", "", $desc);
				//print $desc1;
				if($desc1 == "Amazon Linux AMI x86_64 EBS")
				{
					$query = "INSERT INTO ec2ImageList values($count, '$item->imageId', '$item->name', '$desc1', \"Amazon EC2\", NULL);";
					++$count;
					doQuery($query, 305);
				}
				break;
			}
		}	
	}
/*
	//For Windows Instances

	$xml = simplexml_load_file("/usr/tmp/AMIresponse.xml");
	foreach($xml->imagesSet[0]->item as $item)
	{
		$a=0;
		foreach($item->children() as $child)
		{
			if($child->getName() == "platform")
			{
			        ++$a;
			}

			if($child->getName() == "name")
			{
				++$a;
			}
 
			if($a==2)
			{
				$platf = str_replace('"', "", $item->platform);
				$platf1 = str_replace("'", "", $platf);
				$query = "INSERT INTO ec2ImageList values($count, '$item->imageId', '$item->name', '$platf1', \"Amazon EC2\", NULL)";			
				++$count;
				doQuery($query, 305);
				break;
			}
		}
	}
*/
}

////////////////////////////////////////////////////////////////////////////////
///
/// \fn createInstance($parameters, $host, $time, $AMIID, $numofins)
///
/// \param $parameters - Specifies the parameters to create instance 
/// \param $host - Hostname to connect
/// \param $AMIID - AMI ID of the instance requested
/// \param $numofins - Number of instances of the image requested 
///
/// \brief Parses the received XML file and retrieves the Images offered by the providers
///
////////////////////////////////////////////////////////////////////////////////
function createInstance($parameters, $host, $AMIID, $numofins)
{
	populateCredentials();
	global $AWSKEY, $AWSSECRET;
	// Build out the variables
	$domain = "http://$host/";
	$parameters['ImageId'] = $AMIID;
	$parameters['MinCount'] = 1;
	$parameters['MaxCount'] = $numofins;
	$parameters['InstanceType'] = 't1.micro';   
	$parameters['SecurityGroupId.1'] = 'quick-start-1';
	$parameters['KeyName'] = 'cloud_team5';      

	$parameters['AWSAccessKeyId'] = $AWSKEY; //'AKIAJOWEQSVMR4EJ7N7Q';
	$parameters['Timestamp'] = date('c');
	$parameters['Version'] = '2012-03-01';
	$parameters['SignatureMethod'] = 'HmacSHA256';
	$parameters['SignatureVersion'] = '2';

	// Write the signature
	$signature = "GET\n";
	$signature .= "$host\n";
	$signature .= "/\n";

	$sigparams = $parameters;
	// var_dump($sigparams);
	ksort($sigparams);

	$first = true;
	foreach($sigparams as $key=>$param) {
		//echo "Key: $key; Value: $param<br />\n";
		$signature .= (!$first ? '&' : '') . rawurlencode($key) . '=' . rawurlencode($param);
		$first = false;
	}
	//echo $signature;
	//$signature = hash_hmac('sha256', $signature, 'sY3S+6M0zh4TSMaoLSY6dmqULHD8jsk3GiuXyq1s', true);
	$signature = hash_hmac('sha256', $signature, $AWSSECRET, true);
	$signature = base64_encode($signature);
	//  echo $signature;
	$parameters['Signature'] = $signature;
	$url = $domain . '?';
	$first = true;
	foreach($parameters as $key=>$param) {
		$url .= (!$first ? '&' : '') . rawurlencode($key) . '=' . rawurlencode($param);
		$first = false;
	}

	$dom = new DOMDocument();
	$dom->load($url);
	$dom->save('/usr/tmp/createinstance.xml');
	readInstanceID($AMIID);
}

////////////////////////////////////////////////////////////////////////////////
///
/// \fn readInstanceID($amiid)
///
/// \brief Parses the received XML file to get the reservation ID
///
////////////////////////////////////////////////////////////////////////////////
function readInstanceID($amiid)
{
	global $count;
	$xml = simplexml_load_file("/usr/tmp/createinstance.xml");
	$request_id= $xml->children();

	print "<h2>Acquire Confirmation</h2>\n";
	print "<br>\n";
	print "<p>Successfully created the following resources!</p>\n";
	print "<br>\n";
	$query = "SELECT max(id) from ec2BrokeredInstances";
	$execq = doQuery($query, 101);

	if(empty($execq))
	{
		$count = 0;
		//print "Table is empty and the count is set to zero\n";
	}
	else
	{
		$row = mysql_fetch_row($execq);
		$count = $row[0];
	}
	
	print "<TABLE border=1>\n";
	print "<TR><TH align=center>Name</TH><TH align=center>Instance ID</TH></TR>\n";		
	$i = 0;
	foreach($xml->instancesSet[$i]->item as $item)
	{
		++$i;
		if($count == 0)
		{
			$count = 1;
		}
		else
		{
			++$count;
		}

		$query = "INSERT INTO ec2BrokeredInstances (`id`, `instanceid`, `ami_id`, `duration`, `notes`, `status`) values ($count, '$item->instanceId', '$amiid', NULL, 'EC2 Instances', 0)";
		
		doQuery($query, 305);

		$query1 = "SELECT ami_name from ec2ImageList where ami_id=\"$item->imageId\"";
		$execq = doQuery($query1, 101);

		$row = mysql_fetch_row($execq);
                $imagename = $row[0];
		print "<TR><TD align=center>$imagename</TD>\n";
		print "<TD align=center>$item->instanceId</TD></TR>\n";
		//echo "Image ID is $item->imageId\n";

		addToDB("Amazon EC2", $imagename, $amiid);
		waitAndShutdown($item->instanceId);
	}
	print "</TABLE>\n";
	
	// Instance goes into running state as it is created......Trying to stop it
//	$params = array('Action' => 'StopInstances');
//	$db = stopInstances($params, 'ec2.amazonaws.com', $xml->instancesSet);	
}

////////////////////////////////////////////////////////////////////////////////
///
/// \fn stopInstances($parameters, $host, $instArray)
///
/// \param $parameters - Specifies the parameters to stop the instances
/// \param $host - Hostname to connect
/// \param $instArray - list of ami ids of instances to be stopped 
///
/// \brief Stops the acquired running instances 
///
////////////////////////////////////////////////////////////////////////////////
function stopInstances($parameters, $host, $instanceID)
{
	populateCredentials();
	global $AWSKEY, $AWSSECRET;
	// Build out the variables
	$domain = "http://$host/";
	$parameters['InstanceId.1'] = $instanceID;'i-20d05b47'; //Use the Image ID to stop
   
	$parameters['AWSAccessKeyId'] = $AWSKEY; //'AKIAJOWEQSVMR4EJ7N7Q';
	$parameters['Timestamp'] = date('c');
	$parameters['Version'] = '2012-03-01';
	$parameters['SignatureMethod'] = 'HmacSHA256';
	$parameters['SignatureVersion'] = '2';

	// Write the signature
	$signature = "GET\n";
	$signature .= "$host\n";
	$signature .= "/\n";

	$sigparams = $parameters;
	// var_dump($sigparams);
	ksort($sigparams);

	$first = true;
	foreach($sigparams as $key=>$param) 
	{
		//echo "Key: $key; Value: $param<br />\n";
		$signature .= (!$first ? '&' : '') . rawurlencode($key) . '=' . rawurlencode($param);
		$first = false;
	}
	//$signature = hash_hmac('sha256', $signature, 'sY3S+6M0zh4TSMaoLSY6dmqULHD8jsk3GiuXyq1s', true);
	$signature = hash_hmac('sha256', $signature, $AWSSECRET, true);
	$signature = base64_encode($signature);
	//  echo $signature;
    
	$parameters['Signature'] = $signature;
	$url = $domain . '?';
	$first = true;
	foreach($parameters as $key=>$param) {
		$url .= (!$first ? '&' : '') . rawurlencode($key) . '=' . rawurlencode($param);
		$first = false;
	}
//	echo $url;

	$output = file_get_contents(trim($url));
//	echo "\n";
//	echo $output;  
//	return $output;
}
////////////////////////////////////////////////////////////////////////////////
///
/// \fn addToDB($prov, $imagename)
/// 
/// \param $prov - gets the provider name
/// \param $imagename - gets the name of the image to store in DB
///
/// \brief displays the statistics associated with the borrowed resources
///
////////////////////////////////////////////////////////////////////////////////
function addToDB($prov, $imagename, $amiid)
{
	global $dot, $resid, $imageid, $resgid, $resmid, $imname;
	$dot = 0;
	addEC2NonLocalImage($imagename, $amiid);

	static $count;

	$count = getNumberOfEC2Computers();
	$count +=1;
	
	$compID = addEC2NonLocalComputer($count);
}
////////////////////////////////////////////////////////////////////////////////
///
/// \fn addNonLocalImage($data)
///
/// \param $data - an array with the following indexes:\n
/// name, prettyname, ownerid, platformid, OSid,
///
/// \brief adds a image to the image table
///
////////////////////////////////////////////////////////////////////////////////
function addEC2NonLocalImage($imagename, $amiid) {
	global $dot, $resid, $imageid, $resgid, $resmid, $imname;
	$dot = 0;
	
	$imname = "EC2-$imagename";

	
	$ownerid = 1;
	//if image with same name already exists just return imageid
	$select_query = "SELECT id from image where name='$imname'";
        $iqh = doQuery($select_query, 101);
        if(mysql_num_rows($iqh)) {
                $row = mysql_fetch_row($iqh);
                return $row[0];
        }
	//get corresponding "ec2" OS id from OS table
	$osid = 1;
	$os_query = "select id from OS where type='ec2' LIMIT 1";
        $oqh = doQuery($os_query, 101);
        if(mysql_num_rows($oqh)) {
                $row = mysql_fetch_row($oqh);
                $osid = $row[0];
        } else {
                return NULL;
        }
	//insert image into image table
	$query = "INSERT INTO image "
	       .         "(name, "
	       .	 "prettyname, "
	       .         "ownerid, "
	       .         "platformid, "
	       .         "OSid) "
	       . "VALUES ('$imname', "
	       .	 "'$imagename', "
	       .         "1, "
	       .         "1, "
	       .         "$osid)";
	doQuery($query, 205);

	// get last insert id
	$qh = doQuery("SELECT LAST_INSERT_ID() FROM image", 206);
	if(! $row = mysql_fetch_row($qh)) {
		abort(207);
	}
	$imageid = $row[0];
	// add entry in resource table
        $query = "INSERT INTO resource "
                         .        "(resourcetypeid, "
                         .        "subid) "
                         . "VALUES (13, "
                         .         "$imageid)";
        doQuery($query, 209);
        $qh = doQuery("SELECT LAST_INSERT_ID() FROM resource", 101);
        $row = mysql_fetch_row($qh);
        $resid = $row[0];
	//add image revision 
	$query = "INSERT INTO imagerevision "
               .        "(imageid, "
               .        "userid, "
               .        "datecreated, "
               .        "production, "
               .        "imagename) "
               . "VALUES ($imageid, "
               .        "1, "
               .        "NOW(), "
               .        "1, "
               .        "'$imagename') ";
        doQuery($query, 101);
	
	// add into resource group created
	$result = mysql_query("SELECT id FROM resourcegroup WHERE name = 'ec2_images'");
        if ($result) {
            $rc = mysql_result($result, 0);
			if ($rc) {
				$query = sprintf("INSERT INTO resourcegroupmembers(resourceid, resourcegroupid) VALUES(%d, %d)",$resid, $rc);
		                    doQuery($query, 101);
			}
        }
	//add reference of image added into ec2Resources table
	$query = sprintf("INSERT IGNORE INTO ec2Resources(resourceid, type) VALUES(%d, 13)",$imageid);
        doQuery($query, 101);
	//add image reference and image id mapping for other cloud
	
	$query = "INSERT IGNORE INTO ec2Image(imageid, amiid, type) VALUES($imageid,'$amiid' , 'ec2image')";
	doQuery($query, 101);
	return $imageid;
}
////////////////////////////////////////////////////////////////////////////////
///
/// \fn addNonLocalComputer($data)
///
/// \param $data - an array with the following indexes:\n
/// ipaddress, stateid, platformid, scheduleid,
/// ram, numprocs, procspeed, network, hostname, type
///
/// \brief adds a computer to the computer table
///
////////////////////////////////////////////////////////////////////////////////
function addEC2NonLocalComputer($count) {
	$notes = 'NULL';
	//retrieve provisioning id of vcl2vcl module
      	$result = mysql_query('select * from provisioning where name = "ec2"');
	if ($result) {
		$rc = mysql_fetch_assoc($result);
		$provisioningid=$rc['id'];
	}
	else {
		$provisioningid=8;
	}
	//append vcl against hostnames of computers
	$hostname = "ec2vm".$count;
	//check if already there is entry with the same hostname, if so just return
	$select_query = "select id from computer where hostname LIKE '$hostname'";
	$qh = doQuery($select_query, 101);
        if(mysql_num_rows($qh)) {
		$row = mysql_fetch_row($qh);
                return $row[0];
        }
	$query = "INSERT INTO computer "
               .        "(stateid, "
               .        "ownerid, "
               .        "platformid, "
               .        "scheduleid, "
               .        "currentimageid, "
               .        "RAM, "
               .        "procnumber, "
               .        "procspeed, "
               .        "network, "
               .        "hostname, "
               .        "type, "
               .        "notes, "
	       .	"location, "
               .        "provisioningid) "
               . "VALUES (2, "
               .         "1, "
               .         "1, "
               .         "1, "
               .         "4, "
               .         "1024, "
               .         "1, "
               .         "2000, "
               .         "1000, "
               .         "'$hostname', "
               .         "'blade', "
               .         "$notes, "
	       .	 "'vcl', "
               .         "$provisioningid)";
        doQuery($query, 195);
        $compid = dbLastInsertID();
	$query = "INSERT INTO resource "
                         .        "(resourcetypeid, "
                         .        "subid) "
                         . "VALUES (12, "
                         .         "$compid)";
        doQuery($query, 198);
        $resid = dbLastInsertID();
	print "Resource added with resource ID: $resid<br>";    //Added by Chaitanya

        // add computer into vcl_computers resourcegroup id
	$result = mysql_query("SELECT id FROM resourcegroup WHERE name = 'ec2_computers'");
        if ($result) {
                $rc = mysql_result($result, 0);
                if ($rc) {
                        $query = sprintf("INSERT INTO resourcegroupmembers(resourceid, resourcegroupid) VALUES(%d, %d)",$resid, $rc);
                        doQuery($query, 101);
			print "Resource group added\n";  //Added by Chaitanya
                }
        }
	//add reference of computer added into vclResource table
        $query = sprintf("INSERT INTO ec2Resources(resourceid, type) VALUES(%d, 12)",$compid);
        doQuery($query, 101);

	return $compid;
}

////////////////////////////////////////////////////////////////////////////////
///
/// \fn getNumberOfEC2Computers()
/// \brief get count of number of ec2vm's present in the computer table.
///
////////////////////////////////////////////////////////////////////////////////
function getNumberOfEC2Computers(){
	$result = mysql_query("SELECT count(*) FROM computer WHERE name LIKE 'ec2vm%'");
        if ($result) {
                $rc = mysql_result($result, 0);
                return $rc;
        }
}

////////////////////////////////////////////////////////////////////////////////
///
/// \fn waitAndShutdown($instanceID)
/// \brief get count of number of ec2vm's present in the computer table.
///
////////////////////////////////////////////////////////////////////////////////
function waitAndShutdown($instanceID){
	sleep(120);
	$params = array('Action' => 'StopInstances');
        stopInstances($params, 'ec2.amazonaws.com', $instanceID);	
}

////////////////////////////////////////////////////////////////////////////////
///
/// \fn releaseEC2BrokerResources()
/// \release the brokered resource.
///
////////////////////////////////////////////////////////////////////////////////
function releaseEC2BrokerResources($instanceid, $amiid){

	// Remove entries from image table if this is the only instance of that image.
	$countquery = mysql_query("SELECT count(*) FROM ec2BrokeredInstances WHERE ami_id = '$amiid'");
	if($countquery)
	{
		$sameImageCount = mysql_result($countquery,0);
	}
	if($sameImageCount == 1)
	{
		global $image_id, $resource_id;
		// Get image id from ec2Image
		$get_image_id = mysql_query("SELECT imageid FROM ec2Image WHERE amiid = '$amiid'");
		if($get_image_id)
		{
			$image_id = mysql_result($get_image_id,0);
		}
		
		// Delete from resource table
		$deleteResource = mysql_query("DELETE FROM resource WHERE subid = $image_id AND resourcetypeid = 13");
		
		// Delete the image entry from image revision table.
		$deleteRevision = mysql_query("DELETE FROM imagerevision WHERE imageid = $image_id");
		
		// Delete from log all image entries
		$deleteLog = mysql_query("DELETE FROM log WHERE imageid = $image_id");
		
		sleep(5);
		// Delete the image entry from image table.
		$deleteImage = mysql_query("DELETE FROM image WHERE id=$image_id");
		$deleteImage = mysql_query("DELETE FROM image WHERE id=$image_id");
	}
	
	// Delete from ec2Image table
	$deleteEc2Image = mysql_query("DELETE FROM ec2Image WHERE imageid = $image_id");
	
	// Select 1 computer from ec2vm computer list to remove.
	$selectComputerToDelete = mysql_query("SELECT id FROM computer WHERE stateid=2 AND hostname LIKE 'ec2vm%' LIMIT 1");
	if($selectComputerToDelete)
	{
		$computer_id = mysql_result($selectComputerToDelete,0);
		if($computer_id)
		{
			// Delete from resource table the computer entry.
			$deleteCompResource = mysql_query("DELETE FROM resource WHERE subid = $computer_id AND resourcetypeid=12");
		}
		
		// Delete the computer from computer table
		$deleteComputer = mysql_query("DELETE FROM computer WHERE id=$computer_id");
	}
	
	// Remove entry from ec2BrokeredResources
	$deleteInstance = mysql_query("DELETE FROM ec2BrokeredInstances WHERE instanceid = '$instanceid'");
	
	// Call to terminate EC2 instance
	// terminateEC2Instance($instanceid);
	$params = array('Action' => 'TerminateInstances');
	stopInstances($params, 'ec2.amazonaws.com', $instanceid);
}
?>

